package com.example.appointment.service.impl;

import com.example.appointment.dto.ForumStatsDTO;
import com.example.appointment.dto.PostDTO;
import com.example.appointment.entity.Post;
import com.example.appointment.entity.PostCategory;
import com.example.appointment.entity.User;
import com.example.appointment.repository.CommentRepository;
import com.example.appointment.repository.PostCategoryRepository;
import com.example.appointment.repository.PostFavoriteRepository;
import com.example.appointment.repository.PostRepository;
import com.example.appointment.repository.UserRepository;
import com.example.appointment.service.PostService;
import com.example.appointment.service.UserService;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PostServiceImpl implements PostService {
    private final PostRepository postRepository;
    private final PostCategoryRepository categoryRepository;
    private final UserService userService;
    private final UserRepository userRepository;
    private final CommentRepository commentRepository;
    private final PostFavoriteRepository postFavoriteRepository;

    public PostServiceImpl(
            PostRepository postRepository,
            PostCategoryRepository categoryRepository,
            UserService userService,
            UserRepository userRepository,
            CommentRepository commentRepository,
            PostFavoriteRepository postFavoriteRepository) {
        this.postRepository = postRepository;
        this.categoryRepository = categoryRepository;
        this.userService = userService;
        this.userRepository = userRepository;
        this.commentRepository = commentRepository;
        this.postFavoriteRepository = postFavoriteRepository;
    }

    @Override
    public Page<PostDTO> getPosts(Pageable pageable) {
        return postRepository.findAllByOrderByCreatedAtDesc(pageable)
                .map(this::convertToDTO);
    }

    @Override
    public PostDTO getPost(Long id) {
        Post post = postRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("帖子不存在"));
        return convertToDTO(post);
    }

    @Override
    @Transactional
    public PostDTO createPost(PostDTO postDTO) {
        User currentUser = userService.getCurrentUser();
        
        // 如果没有指定分类，使用默认分类
        Long categoryId = postDTO.getCategoryId();
        if (categoryId == null) {
            categoryId = 1L; // 默认分类ID
        }
        
        PostCategory category = categoryRepository.findById(categoryId)
                .orElseThrow(() -> new RuntimeException("分类不存在"));

        Post post = new Post();
        post.setTitle(postDTO.getTitle());
        post.setContent(postDTO.getContent());
        post.setCategory(category);
        post.setAuthor(currentUser);
        post.setLikes(0);
        post.setViews(0);
        
        // 处理标签信息
        if (postDTO.getTags() != null && !postDTO.getTags().isEmpty()) {
            String tagsString = String.join(",", postDTO.getTags());
            post.setTags(tagsString);
        }

        Post savedPost = postRepository.save(post);
        return convertToDTO(savedPost);
    }

    @Override
    @Transactional
    public PostDTO updatePost(Long id, PostDTO postDTO, Long userId) {
        Post post = postRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("帖子不存在"));

        if (!post.getAuthor().getId().equals(userId)) {
            throw new IllegalStateException("您没有权限更新这篇帖子");
        }

        post.setTitle(postDTO.getTitle());
        post.setContent(postDTO.getContent());

        Post updatedPost = postRepository.save(post);
        return convertToDTO(updatedPost);
    }

    @Override
    @Transactional
    public void deletePost(Long id) {
        Post post = postRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("帖子不存在"));
        
        try {
            // 删除帖子前先删除与该帖子关联的所有评论
            commentRepository.deleteByPostId(id);
            
            // 删除帖子前先删除与该帖子关联的所有收藏
            postFavoriteRepository.deleteByPostId(id);
            
            // 然后删除帖子
            postRepository.delete(post);
        } catch (Exception e) {
            throw new RuntimeException("删除帖子失败: " + e.getMessage(), e);
        }
    }

    @Override
    @Transactional
    public void likePost(Long id) {
        if (!postRepository.existsById(id)) {
            throw new EntityNotFoundException("帖子不存在");
        }
        postRepository.incrementLikes(id);
    }

    @Override
    public Page<PostDTO> searchPosts(String keyword, Pageable pageable) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return getPosts(pageable);
        }
        return postRepository.searchPosts(keyword.trim(), pageable)
                .map(this::convertToDTO);
    }

    @Override
    public Page<PostDTO> getPostsByAuthor(Long authorId, Pageable pageable) {
        return postRepository.findByAuthorIdOrderByCreatedAtDesc(authorId, pageable)
                .map(this::convertToDTO);
    }

    @Override
    public Page<PostDTO> getHotPosts(Pageable pageable) {
        return postRepository.findAllByOrderByLikesDescCreatedAtDesc(pageable)
                .map(this::convertToDTO);
    }

    @Override
    public Page<PostDTO> getLatestPosts(Pageable pageable) {
        return postRepository.findAllByOrderByCreatedAtDesc(pageable)
                .map(this::convertToDTO);
    }

    @Override
    public Page<PostDTO> getPostsByCategory(Long categoryId, Pageable pageable) {
        return postRepository.findByCategoryIdOrderByCreatedAtDesc(categoryId, pageable)
                .map(this::convertToDTO);
    }

    @Override
    public Page<PostDTO> getPostsByTags(String tags, Pageable pageable) {
        // 支持多个标签，用逗号分隔
        String tagsPattern = "%" + tags + "%";
        return postRepository.findByTagsLikeOrderByCreatedAtDesc(tagsPattern, pageable)
                .map(this::convertToDTO);
    }

    @Override
    public List<PostDTO> getTrendingPosts(int limit) {
        // 获取一周前的时间
        LocalDateTime oneWeekAgo = LocalDateTime.now().minusDays(7);
        Pageable pageable = PageRequest.of(0, limit);
        
        // 查询趋势帖子
        List<Post> trendingPosts = postRepository.findTrendingPosts(oneWeekAgo, pageable);
        return trendingPosts.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public ForumStatsDTO getForumStats() {
        ForumStatsDTO stats = new ForumStatsDTO();
        
        // 获取今天的开始时间
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        
        // 设置统计信息
        stats.setTotalPosts(postRepository.countTotalPosts());
        stats.setTotalComments(commentRepository.countTotalComments());
        stats.setTotalUsers(userRepository.count());
        stats.setPostsToday(postRepository.countTodayPosts(todayStart));
        stats.setCommentsToday(commentRepository.countTodayComments(todayStart));
        
        return stats;
    }

    @Override
    public Page<PostDTO> getPostsByAuthorId(Long authorId, Pageable pageable) {
        Page<Post> posts = postRepository.findByAuthorId(authorId, pageable);
        return posts.map(this::convertToDTO);
    }

    private PostDTO convertToDTO(Post post) {
        PostDTO dto = new PostDTO();
        dto.setId(post.getId());
        dto.setTitle(post.getTitle());
        dto.setContent(post.getContent());
        dto.setCategoryId(post.getCategory().getId());
        dto.setAuthorName(post.getAuthor().getUsername());
        dto.setLikes(post.getLikes());
        dto.setViews(post.getViews());
        dto.setCreatedAt(post.getCreatedAt());
        dto.setUpdatedAt(post.getUpdatedAt());
        
        // 处理标签信息
        if (post.getTags() != null && !post.getTags().isEmpty()) {
            dto.setTags(post.getTags());
        }
        
        return dto;
    }
} 